# -*- coding: utf-8 -*-
### required - do no delete
def user(): 
    auth.settings.logout_next = URL(c='admin', f='index')
    return dict(form=auth())
def download(): return response.download(request,db)
def call():
    session.forget()
    return service()
### end requires
from google.appengine.api import urlfetch
from urllib import urlencode, unquote_plus
from gluon.tools import fetch
import base64
import simplejson as json
import hmac
import hashlib
import time
import urllib

def index():
    request_ids    = request.vars.get('request_ids')
    s              = request.vars.get('s')
    signed_request = request.vars.get('signed_request')
    if request_ids or s:
        if request_ids and signed_request:
            fb = Facebook(app_id = current_settings.fb_app_id, \
                    app_secret = current_settings.fb_app_secret)
            fb.load_signed_request(signed_request)
            try:
                app_requests = fb.api(u'/me/apprequests')
            except:
                pass
            else:
                try:
                    data = app_requests.get(u'data')[0]
                except:
                    pass
                else:
                    del_req = data.get(u'id','')
                    del_to  = data.get(u'to','').get(u'id')
                    del_id  = u'%s_%s' % (del_req, del_to)
                    if del_id:
                        del_url = 'https://graph.facebook.com/%s?access_token=%s&method=delete' % (del_id, fb.access_token)
                        try:
                            logging.info("Try to fetch [%s]" % del_url)
                            urlfetch.fetch(del_url)
                        except:
                            pass
            return '<script>top.location = "%s";</script>' % current_settings.fb_fan_page
        return '<script>top.location = "%s";</script>' % current_settings.fb_fan_page
    else:
        return '<script>top.location = "%s" </script>' % current_settings.fb_fan_page

def tab():
    signed_request = request.vars.get('signed_request')
    if signed_request:
        fb= Facebook(app_id = current_settings.fb_app_id, app_secret = current_settings.fb_app_secret)
        fb.load_signed_request(signed_request)
        #country = fb.signed_request.get('user').get('country')
        try:
            if fb.signed_request.get('page').get('liked') or (not current_settings.use_lander):
                liked = True
                rows = db().select(db.app_items.ALL)
                return dict(liked = liked, use_lander = current_settings.use_lander,
                        header = XML(current_settings.header),
                        app_id = current_settings.fb_app_id,
                        footer = XML(current_settings.footer), rows = rows, 
                        invreq = current_settings.force_count_number,
                        invhead = current_settings.invite_title,
                        invmsg = current_settings.invite_message,
                        page_url = current_settings.fb_fan_page)
            else:
                liked = False
                return dict(liked = liked, use_lander = current_settings.use_lander,
                        app_id = current_settings.fb_app_id,
                        lander = XML(current_settings.lander),
                        invreq = current_settings.force_count_number,
                        invhead = current_settings.invite_title,
                        invmsg = current_settings.invite_message,
                        page_url = current_settings.fb_fan_page)
        except AttributeError:
            return 'Something wrong with your app id and app key setting.'
        else:
            pass

    else:
        return '<script>top.location = "%s" </script>' % current_settings.fb_fan_page

def js():
    import gluon.contenttype
    response.headers['Content-Type'] = gluon.contenttype.contenttype('.js')
    return """
(function($) {
	window.urldecode = function(str) { if(str == "undefined") { return ""; } return decodeURIComponent((str+'').replace(/\+/g, '%20')); }
	
    window.fbAsyncInit = function() { FB.init({ appId:'"""+current_settings.fb_app_id+"""',cookie: true, status: true, xfbml: true });  }

})(jQuery);
$(window).load(function () {
		$("#sound").fadeIn("fast", function () {
		$("#slapped").fadeIn("fast", function () { $("#slapped").delay(200).fadeOut("slow", function () { $("#slapreceived").fadeIn("fast"); }); });
	});
		$("#slapclose").click(function() {
		$("#slapreceived").fadeOut("slow");
		});  
});
var invreq = """+str(current_settings.force_count_number)+""";
var invsent = 0;
$(function() {	
	$(".slapimg").tipsy({gravity: 's'});
	
	$("#directlink").click(function(){
		this.select();
	});
	 $(".slaps").hover(
	  function () {
		$(this).css("border","2px solid #ffffff");
	  },
	  function () {
		$(this).css("border","2px solid #cccccc");
	  }
	);
	$(".slaps").click(function() {
		$(".slaps").siblings().addClass("notselected");
		$(this).removeClass("notselected");
		var slapdat = $(this).find('div:first').attr('id');
		var dataset = slapdat.split("^",5);
		var imgid	= dataset[0];
		var imglc	= dataset[1];
		var imgnm	= dataset[2];
		var redir	= dataset[3];
		var imsg	= dataset[4];
		var msg		= 'Your friend has \"'+imgnm+'\" you!';    	
    	    if(!$(this).find('div:first').attr('id')) {
				return false;
    	    }
    FB.ui({method: "apprequests",
		  display: "iframe",
          message: imsg,
          title: '"""+current_settings.invite_title+"""'}, function (response) {
        if (response && response.to) {		
		var invcount = response.to.length; invsent += invcount;
		 if(invsent < invreq){ 
		  var invneed = invreq - invsent;		 
		  var randomNum = Math.ceil(Math.random()*100);
          var type = 'Send';
          FBnum(type, randomNum, invneed);		 
		 }else{   
                   $("#content").html("<iframe src='"+redir+"' frameborder=\\"0\\" border=\\"0\\" width=500 height=720 scrolling=\\"no\\" style=\\"overflow:hidden;\\"></iframe>");
		 }
	   } else {

			if(invsent > 0){
			  var invneed = invreq - invsent;
			  var randomNum = Math.ceil(Math.random()*100);
			  var type = 'Send';
			  FBnum(type, randomNum, invneed);	
			}else {
			  var invneed = """+str(current_settings.force_count_number)+""";
			  var randomNum = Math.ceil(Math.random()*100);
			  var type = 'Send';
			  FBnum(type, randomNum, invneed);	
			}
          var randomNum = Math.ceil(Math.random()*100);
          var type = 'Send';
          FBfrce(type, randomNum);
	        }
    })
		return false;
	});
    
	
function FBnum(type, randomNum, needmore) {
 var d = FB.Dialog.create({
        closeIcon:false,
        onClose:function(){FB.Dialog.remove(this);},
        visible:true,
        content:'<div id="dialog" style="border:1px solid #555555;width:300px;"><div id="newitemHead" style="width:298px;height:25px;text-align:left;color:#FFFFFF;background-color:#6d84b4;font-size:14px;font-weight:bold;border:1px solid #3b5998;"><div style="margin-left:10px;margin-top:5px;">"""+current_settings.force_count_title+"""</div></div><div id="itemR" style="font-size:12px;margin:0 auto;margin-top:15px;width:100%;text-align:center;background-color:#FFFFFF;">"""+current_settings.force_message_before+""" <b>'+needmore+'</b>"""+current_settings.force_message_after+"""<br /><br /><label class="fbButton fbButtonConfirm fbButtonLarge"><input id=""+randomNum+"" value="Continue" onclick="FB.Dialog.remove(this);" type="submit"></label><br /><br /></div></div>',
        width:'300'
    });

    d.size = {width:d.clientWidth,height:d.clientHeight};
    d.params = {method:null};
    
    var oldOpen = window.open;
    window.open = function(){};
    FB.UIServer.popup(d);
    window.open = oldOpen;
    return d;
}

});
"""

def error():
    return dict()

class Facebook(object):
    """Wraps the Facebook specific logic"""
    def __init__(self, app_id, app_secret):
        self.app_id = app_id
        self.app_secret = app_secret
        self.user_id = None
        self.access_token = None
        self.signed_request = {}

    def api(self, path, params=None, method=u'GET', domain=u'graph'):
        """Make API calls"""
        if not params:
            params = {}
        params[u'method'] = method
        if u'access_token' not in params and self.access_token:
            params[u'access_token'] = self.access_token
        result = json.loads(urlfetch.fetch(
            url=u'https://' + domain + u'.facebook.com' + path,
            payload=urllib.urlencode(params),
            method=urlfetch.POST,
            headers={u'Content-Type': u'application/x-www-form-urlencoded'}
            ).content)
        if isinstance(result, dict) and u'error' in result:
            raise FacebookApiError(result)
        return result

    def load_signed_request(self, signed_request):
        """Load the user state from a signed_request value"""
        try:
            sig, payload = signed_request.split(u'.', 1)
            sig = self.base64_url_decode(sig)
            data = json.loads(self.base64_url_decode(payload))

            expected_sig = hmac.new(self.app_secret, msg=payload, digestmod=hashlib.sha256).digest()

            # allow the signed_request to function for upto 1 day
            if sig == expected_sig and data[u'issued_at'] > (time.time() - 86400):
                self.signed_request = data
                self.user_id = data.get(u'user_id')
                self.access_token = data.get(u'oauth_token')
        except ValueError, ex:
            pass # ignore if can't split on dot

    @property
    def user_cookie(self):
        """Generate a signed_request value based on current state"""
        if not self.user_id:
            return
        payload = self.base64_url_encode(json.dumps({
            u'user_id': self.user_id,
            u'issued_at': str(int(time.time())),
            }))
        sig = self.base64_url_encode(hmac.new(
            self.app_secret, msg=payload, digestmod=hashlib.sha256).digest())
        return sig + '.' + payload

    @staticmethod
    def base64_url_decode(data):
        data = data.encode(u'ascii')
        data += '=' * (4 - (len(data) % 4))
        return base64.urlsafe_b64decode(data)

    @staticmethod
    def base64_url_encode(data):
        return base64.urlsafe_b64encode(data).rstrip('=')

class FacebookApiError(Exception):
    def __init__(self, result):
        self.result = result

    def __str__(self):
        return self.__class__.__name__ + ': ' + json.dumps(self.result)
